package csel.controller;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import csel.controller.dispatchers.AbstractDispatcher;
import csel.controller.factories.ControllerBuilder;
import csel.controller.listeners.AbstractActionListener;
import csel.controller.listeners.KeyboardListener;
import csel.controller.listeners.StatusViewActionListener;
import csel.model.GameFactory;
import csel.model.Model;
import csel.model.Summoner;
import csel.view.AreaViewport;
import csel.view.Splasher;
import csel.view.StatusViewport;

/*
 * This allows you to test view controls against the controller
 */
public class TestControllerWithViewDummy
{
	// THIS IS A DUMMY!!
	static Model model = new Model();
	Splasher splashViewport = new Splasher( model );
	AreaViewport areaViewport = new AreaViewport( model );
	StatusViewport statusViewport = new StatusViewport( model );
	JFrame frame;
	ControllerBuilder c = new ControllerBuilder( 
			model, splashViewport, areaViewport, statusViewport );
	
	private TestControllerWithViewDummy()
	{
		// The ControllerBuilder contructs the 
		// listeners and starts the threads. All
		// dispatchers can be retrieved from this
		// class
		c.contruct();
	}
	
	public static TestControllerWithViewDummy newInstance()
	{
		GameFactory.newGame(new Summoner(), "default", model);
		return new TestControllerWithViewDummy();
	}
	
	// For testing
	public ControllerBuilder getControllerBuilder()
	{
		return this.c;
	}
	public void destroy(){
		killTheThreads();
		frame.setVisible(false);
		frame.dispose();
	}
	public StatusViewActionListener getStatusListener()
	{
		return ((StatusViewActionListener)c.getAList().get(2));
	}
	public void makeView()
	{
		frame = new JFrame("Button Sample");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JButton button1 = new JButton("AVAL");
		JButton button2 = new JButton("SPVAL");
		JButton button3 = new JButton("STVAL");
		JButton button4 = new JButton("KILL!");
		JTextField typingArea = new JTextField(20);
		
		AbstractDispatcher md = c.getModelDispatcher();
		AbstractDispatcher vd = c.getViewDispatcher();
		
		// Retrieve ActionListers and KeyListeners from ControllerBuilder
		ActionListener aval = c.getAList().get(0);
		ActionListener spval = c.getAList().get(1);
		ActionListener stval = c.getAList().get(2);
		KeyListener kval = c.getKList().get(0);
		
		// CommandFactory mcf = new ModelCommandFactory();
		// CommandFactory vcf = new ViewCommandFactory();
		
		// Attach listeners to view controls
		typingArea.setFocusable(true);
		frame.addKeyListener(kval);
		typingArea.addKeyListener(kval);
		button1.addActionListener(aval);
		button2.addActionListener(spval);
		button3.addActionListener(stval);
		
		// Add buttons to layout
		Container contentPane = frame.getContentPane();
		contentPane.add(button1, BorderLayout.EAST);
		contentPane.add(button2, BorderLayout.WEST);
		contentPane.add(button3, BorderLayout.SOUTH);
		contentPane.add(typingArea, BorderLayout.CENTER);

		// A mouse listener (not attached)
		MouseListener mouseListener = new MouseAdapter()
		{
			public void mousePressed(MouseEvent mouseEvent)
			{
				int modifiers = mouseEvent.getModifiers();
				if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK)
				{
					// Mask may not be set properly prior to Java 2
					// See SwingUtilities.isLeftMouseButton() for workaround
					System.out.println("[CONTROLLER] Left button pressed.");
				}
				if ((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK)
				{
					System.out.println("[CONTROLLER] Middle button pressed.");
				}
				if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
				{
					System.out.println("[CONTROLLER] Right button pressed.");
				}
			}

			public void mouseReleased(MouseEvent mouseEvent)
			{
				if (SwingUtilities.isLeftMouseButton(mouseEvent))
				{
					System.out.println("[CONTROLLER] Left button released.");
				}
				if (SwingUtilities.isMiddleMouseButton(mouseEvent))
				{
					System.out.println("[CONTROLLER] Middle button released.");
				}
				if (SwingUtilities.isRightMouseButton(mouseEvent))
				{
					System.out.println("[CONTROLLER] Right button released.");
				}
				System.out.println();
			}
		};
		
		ActionListener killThreads = new ActionListener() 
		{
			public void actionPerformed(ActionEvent e)
			{
				killTheThreads();
			}
		};
		
		button4.addActionListener(killThreads);
		contentPane.add(button4, BorderLayout.NORTH);
		
		// button.addActionListener(actionListener);
		// button.addKeyListener(keyListener);
		// button.addMouseListener(mouseListener);
		// frame.addMouseListener(mouseListener);

		frame.setSize(300, 150);
		frame.setVisible(true);
	}
	
	public void killTheThreads()
	{
		// terminate threads
		Iterator<KeyboardListener> i = c.getKList().iterator();
		while( i.hasNext() )
		{
			i.next().killWorker();
		}
		Iterator<AbstractActionListener> j = c.getAList().iterator();
		while( j.hasNext() )
		{
			j.next().killWorker();
		}
		c.getModelDispatcher().killWorker();
		c.getViewDispatcher().killWorker();
	}
	
	public Model getModel()
	{
		return model;
	}
	
	public static void main(String args[])
	{
//		GameFactory.newGame(new Summoner(), "default", model);
		TestControllerWithViewDummy t = newInstance();
		t.makeView();
	}
}
